#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qmessagebox.h>
#include"fun.h"
#include <unistd.h>
#include <QTimer>
#include "stdio.h"
#include <sys/time.h>
#include <time.h>
#include<string>
#include <signal.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{    
    ui->setupUi(this);
    setWindowTitle("my sniffer by lee");
    QGridLayout *Layout = new QGridLayout;
    Layout->addWidget(ui->tableWidget,0,0,1,5);
    Layout->addWidget(ui->treeWidget,1,0,1,2);
    Layout->addWidget(ui->textEdit,2,0,1,3);
    Layout->addWidget(ui->textEdit_2,2,3,1,2);
    linechart=new LineGraphWidget(0,550);
//    linechart->show();
//    linechart->setWindowFlags(Qt::CustomizeWindowHint|Qt::FramelessWindowHint);
    Layout->addWidget(linechart,1,3,1,2);
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);  //单击选择一行
    ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); //设置只能选择一行，不能多行选中
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);   //设置每行内容不可更改
    ui->tableWidget->verticalHeader()->setVisible(false);
    ui->tableWidget->setAlternatingRowColors(true);                        //设置隔一行变一颜色，即：一灰一白
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->tableWidget->setAutoScroll(true);

    connect(ui->tableWidget,SIGNAL(cellClicked(int,int)),this,SLOT(cellSelected(int,int)));

    // hiden col
    ui->tableWidget->insertColumn(7);
    ui->tableWidget->setColumnHidden(7,1);

    QTextCursor cursor = ui->textEdit->textCursor();
    cursor.movePosition(QTextCursor::End);
    QTextCursor cursor1 = ui->textEdit_2->textCursor();
    cursor1.movePosition(QTextCursor::End);

    sem_init (&mutex2, 0, 0);
   // linechart.show();





//     ui->tableWidget->horizontalHeader()->setStretchLastSection(true); // last colmn
//    ui->tableWidget->resizeColumnsToContents();
//    ui->tableWidget->resizeRowsToContents();

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::closeEvent(QCloseEvent *event)
{
//    QMessageBox::information(this,""," red -> ip\n black -> tcp\n yellow -> udp");
    QMessageBox msgBox(this);
    msgBox.setText("Are you sure?");
    QPushButton *connectButton = msgBox.addButton(tr("OK"), QMessageBox::ActionRole);
    QPushButton *abortButton = msgBox.addButton(tr("Cancel"), QMessageBox::ActionRole);
    msgBox.exec();
    if (msgBox.clickedButton() == connectButton) {
         kill(getpid(), SIGINT);
    } else if (msgBox.clickedButton() == abortButton) {
         msgBox.close(); event->ignore();
    }
}


void MainWindow::cellSelected(int nrow,int ncol){
//    QMessageBox::information(this, "",
//                             "Cell at row "+QString::number(nrow)+
//                             " column "+QString::number(ncol)+ " was double clicked.");
//    this->update();
    ncol++;
    QString str,a;
    str=ui->tableWidget->item(nrow,7)->text();
    int tmp=str.toInt(0,10);
    str=ui->tableWidget->item(nrow,4)->text();
    if(a.operator =("ARP")==str){
        ui->treeWidget->clear();
        ui->treeWidget->addTopLevelItem(allarp[tmp].eth_hdr.Gettree());
        ui->treeWidget->addTopLevelItem(allarp[tmp].arp_hdr.Gettree());
        ui->treeWidget->addTopLevelItem(allarp[tmp].Gettree());

        ui->textEdit->clear();
        ui->textEdit_2->clear();
        text_display(allarp[tmp].all,(int)(allarp[tmp].pkt_hdr.caplen));
        text2_display(allarp[tmp].all,(int)(allarp[tmp].pkt_hdr.caplen));
    }
    else if(a.operator =("ICMP")==str){
        ui->treeWidget->clear();
        ui->treeWidget->addTopLevelItem(allicmp[tmp].eth_hdr.Gettree());
        ui->treeWidget->addTopLevelItem(allicmp[tmp].ip_hdr.Gettree());
        ui->treeWidget->addTopLevelItem(allicmp[tmp].icmp_hdr.Gettree());
        ui->treeWidget->addTopLevelItem(allicmp[tmp].Gettree());

        ui->textEdit->clear();
        ui->textEdit_2->clear();
        text_display(allicmp[tmp].all,(int)(allicmp[tmp].pkt_hdr.caplen));
        text2_display(allicmp[tmp].all,(int)(allicmp[tmp].pkt_hdr.caplen));
    }
    else if(a.operator =("UDP")==str){
        ui->treeWidget->clear();
        ui->treeWidget->addTopLevelItem(alludp[tmp].eth_hdr.Gettree());
        ui->treeWidget->addTopLevelItem(alludp[tmp].ip_hdr.Gettree());
        ui->treeWidget->addTopLevelItem(alludp[tmp].udp_hdr.Gettree());
        ui->treeWidget->addTopLevelItem(alludp[tmp].Gettree());
        //text edit
        ui->textEdit->clear();
        ui->textEdit_2->clear();
        text_display(alludp[tmp].all,(int)(alludp[tmp].pkt_hdr.caplen));
        text2_display(alludp[tmp].all,(int)(alludp[tmp].pkt_hdr.caplen));

    }
    else if(a.operator =("TCP")==str){
        ui->treeWidget->clear();
        ui->treeWidget->addTopLevelItem(alltcp[tmp].eth_hdr.Gettree());
        ui->treeWidget->addTopLevelItem(alltcp[tmp].ip_hdr.Gettree());
        ui->treeWidget->addTopLevelItem(alltcp[tmp].tcp_hdr.Gettree());
        ui->treeWidget->addTopLevelItem(alltcp[tmp].Gettree());
        //text edit
        ui->textEdit->clear();
        ui->textEdit_2->clear();
        text_display(alltcp[tmp].all,(int)(alltcp[tmp].pkt_hdr.caplen));
        text2_display(alltcp[tmp].all,(int)(alltcp[tmp].pkt_hdr.caplen));
    }
    else {}



//
}

void MainWindow::text2_display(u_char * a,int lentmp){
    int i;
    QString str;
    for(i=0;i<lentmp;i++){
        str.sprintf("%c",*(a+i));
        ui->textEdit_2->insertPlainText(str);
    }

}
void MainWindow::text_display(u_char * a,int lentmp){
    int total=16;int i,j;
    QString str;
    for(i=0;i<(lentmp/16);i++){
        str.sprintf("%04X",total);
        ui->textEdit->insertPlainText(str+"\x20\x20\x20\x20\x20");
        for(j=0;j<16;j++)
        {
            if(j==8){ui->textEdit->insertPlainText("\x20\x20\x20\x20");}
            int tmp=i*16+j;
            str.sprintf("%02X ",*(a+tmp));
            ui->textEdit->insertPlainText(str);
        }
//        ui->textEdit->insertPlainText("\x20\x20\x20\x20\x20");
//        for(j=0;j<16;j++)
//        {
//            int tmp=i*16+j;
//            str.sprintf("%c",*(a+tmp));
//            ui->textEdit->insertPlainText(str);
//        }
        ui->textEdit->insertPlainText("\n");
        total=total+16;
    }
    total=total-16;
    str.sprintf("%04X",lentmp);
    ui->textEdit->insertPlainText(str+"\x20\x20\x20\x20\x20");
    for(i=0;i<(lentmp%16);i++){
        if(i==8){ui->textEdit->insertPlainText("\x20\x20\x20\x20");}
        str.sprintf("%02X ",*(a+total+i));
        ui->textEdit->insertPlainText(str);
    }
//    ui->textEdit->insertPlainText("\x20\x20\x20\x20\x20");
//    for(i=0;i<lentmp%16;i++){
//        str.sprintf("%c",*(a+total+i));
//        ui->textEdit->insertPlainText(str);
//    }

}


void MainWindow::arp_display(){
    //table widget

    int row = ui->tableWidget->rowCount();
    ui->tableWidget->insertRow(row);
    QString str;
    double timetmp=allarp[arpn].pkt_hdr.ts.tv_sec+double(allarp[arpn].pkt_hdr.ts.tv_usec/double(1000000))-cap_stime;
    str.sprintf("%f",timetmp);
//    str.sprintf("%u.%u\n", allarp[arpn].pkt_hdr.ts.tv_sec, (allarp[arpn].pkt_hdr.ts.tv_usec/1000000));
    ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(row+1)));
    ui->tableWidget->setItem(row,1,new QTableWidgetItem(str));
    ui->tableWidget->setItem(row,2,new QTableWidgetItem(allarp[arpn].arp_hdr.Getarp_source_ip_address()));
    ui->tableWidget->setItem(row,3,new QTableWidgetItem(allarp[arpn].arp_hdr.Getarp_destination_ip_address()));
    ui->tableWidget->setItem(row,4,new QTableWidgetItem("ARP"));
    str.sprintf("%i",allarp[arpn].pkt_hdr.caplen);
    ui->tableWidget->setItem(row,5,new QTableWidgetItem(str));
    ui->tableWidget->setItem(row,6,new QTableWidgetItem(allarp[arpn].arp_hdr.Getarp_hardware_type()));
    ui->tableWidget->setItem(row,7,new QTableWidgetItem(QString::number(allarp[arpn].arpnum)));

    //tree widget

    ui->treeWidget->clear();
    ui->treeWidget->addTopLevelItem(allarp[arpn].eth_hdr.Gettree());
    ui->treeWidget->addTopLevelItem(allarp[arpn].arp_hdr.Gettree());
    ui->treeWidget->addTopLevelItem(allarp[arpn].Gettree());

    //textedit
    ui->textEdit->clear();ui->textEdit_2->clear();
    text_display(allarp[arpn].all,(int)(allarp[arpn].pkt_hdr.caplen));
    text2_display(allarp[arpn].all,(int)(allarp[arpn].pkt_hdr.caplen));



    this->update();
}

void MainWindow::icmp_display(){
    // table widget

     int row = ui->tableWidget->rowCount();
     ui->tableWidget->insertRow(row);
     QString str;
     double timetmp=allicmp[icmpn].pkt_hdr.ts.tv_sec+double(allicmp[icmpn].pkt_hdr.ts.tv_usec/double(1000000))-cap_stime;
     str.sprintf("%f",timetmp);
//     str.sprintf("%u.%u\n", allicmp[icmpn].pkt_hdr.ts.tv_sec, (allicmp[icmpn].pkt_hdr.ts.tv_usec/1000000));
     ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(row+1)));
     ui->tableWidget->setItem(row,1,new QTableWidgetItem(str));
     ui->tableWidget->setItem(row,2,new QTableWidgetItem(allicmp[icmpn].ip_hdr.Getip_souce_address()));
     ui->tableWidget->setItem(row,3,new QTableWidgetItem(allicmp[icmpn].ip_hdr.Getip_destination_address()));
     ui->tableWidget->setItem(row,4,new QTableWidgetItem("ICMP"));
     str.sprintf("%i",allicmp[icmpn].pkt_hdr.caplen);
     ui->tableWidget->setItem(row,5,new QTableWidgetItem(str));
     ui->tableWidget->setItem(row,6,new QTableWidgetItem(allicmp[icmpn].icmp_hdr.Geticmp_type()));
     ui->tableWidget->setItem(row,7,new QTableWidgetItem(QString::number(allicmp[icmpn].icmpnum)));

     // tree widget

     ui->treeWidget->clear();
     ui->treeWidget->addTopLevelItem(allicmp[icmpn].eth_hdr.Gettree());
     ui->treeWidget->addTopLevelItem(allicmp[icmpn].ip_hdr.Gettree());
     ui->treeWidget->addTopLevelItem(allicmp[icmpn].icmp_hdr.Gettree());
     ui->treeWidget->addTopLevelItem(allicmp[icmpn].Gettree());

     //text widget
     ui->textEdit->clear();ui->textEdit_2->clear();
     text_display(allicmp[icmpn].all,(int)(allicmp[icmpn].pkt_hdr.caplen));
     text2_display(allicmp[icmpn].all,(int)(allicmp[icmpn].pkt_hdr.caplen));

     this->update();
}
void MainWindow::tcp_display(){
    //table widget

    int row = ui->tableWidget->rowCount();
    ui->tableWidget->insertRow(row);
    QString str;
    double timetmp=alltcp[tcpn].pkt_hdr.ts.tv_sec+double(alltcp[tcpn].pkt_hdr.ts.tv_usec/double(1000000))-cap_stime;
    str.sprintf("%f",timetmp);

//    str.sprintf("%u.%u\n", alltcp[tcpn].pkt_hdr.ts.tv_sec, (alltcp[tcpn].pkt_hdr.ts.tv_usec/1000000));
    ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(row+1)));
    ui->tableWidget->setItem(row,1,new QTableWidgetItem(str));
    ui->tableWidget->setItem(row,2,new QTableWidgetItem(alltcp[tcpn].ip_hdr.Getip_souce_address()));
    ui->tableWidget->setItem(row,3,new QTableWidgetItem(alltcp[tcpn].ip_hdr.Getip_destination_address()));
    ui->tableWidget->setItem(row,4,new QTableWidgetItem("TCP"));
    str.sprintf("%i",alltcp[tcpn].pkt_hdr.caplen);
    ui->tableWidget->setItem(row,5,new QTableWidgetItem(str));
    ui->tableWidget->setItem(row,6,new QTableWidgetItem(alltcp[tcpn].tcp_hdr.Gettype()));
    ui->tableWidget->setItem(row,7,new QTableWidgetItem(QString::number(alltcp[tcpn].tcpnum)));

    //tree widget

    ui->treeWidget->clear();
    ui->treeWidget->addTopLevelItem(alltcp[tcpn].eth_hdr.Gettree());
    ui->treeWidget->addTopLevelItem(alltcp[tcpn].ip_hdr.Gettree());
    ui->treeWidget->addTopLevelItem(alltcp[tcpn].tcp_hdr.Gettree());
    ui->treeWidget->addTopLevelItem(alltcp[tcpn].Gettree());


    //text edit
    ui->textEdit->clear(); ui->textEdit_2->clear();
    text_display(alltcp[tcpn].all,(int)(alltcp[tcpn].pkt_hdr.caplen));
    text2_display(alltcp[tcpn].all,(int)(alltcp[tcpn].pkt_hdr.caplen));




    this->update();
//    ui->tableWidget->insertRow(1); this->update();
}
void MainWindow::udp_display(){
    // table widget

    int row = ui->tableWidget->rowCount();
    ui->tableWidget->insertRow(row);
    QString str;
    double timetmp=alludp[udpn].pkt_hdr.ts.tv_sec+double(alludp[udpn].pkt_hdr.ts.tv_usec/double(1000000))-cap_stime;
    str.sprintf("%f",timetmp);
//    str.sprintf("%u.%u\n", alludp[udpn].pkt_hdr.ts.tv_sec, (alludp[udpn].pkt_hdr.ts.tv_usec/1000000));
    ui->tableWidget->setItem(row,0,new QTableWidgetItem(QString::number(row+1)));
    ui->tableWidget->setItem(row,1,new QTableWidgetItem(str));
    ui->tableWidget->setItem(row,2,new QTableWidgetItem(alludp[udpn].ip_hdr.Getip_souce_address()));
    ui->tableWidget->setItem(row,3,new QTableWidgetItem(alludp[udpn].ip_hdr.Getip_destination_address()));
    ui->tableWidget->setItem(row,4,new QTableWidgetItem("UDP"));
    str.sprintf("%i",alludp[udpn].pkt_hdr.caplen);
    ui->tableWidget->setItem(row,5,new QTableWidgetItem(str));
    ui->tableWidget->setItem(row,6,new QTableWidgetItem(alludp[udpn].udp_hdr.Gettype()));
    ui->tableWidget->setItem(row,7,new QTableWidgetItem(QString::number(alludp[udpn].udpnum)));

    //tree widget

    ui->treeWidget->clear();
    ui->treeWidget->addTopLevelItem(alludp[udpn].eth_hdr.Gettree());
    ui->treeWidget->addTopLevelItem(alludp[udpn].ip_hdr.Gettree());
    ui->treeWidget->addTopLevelItem(alludp[udpn].udp_hdr.Gettree());
    ui->treeWidget->addTopLevelItem(alludp[udpn].Gettree());

    //text edit
    ui->textEdit->clear();ui->textEdit_2->clear();
    text_display(alludp[udpn].all,(int)(alludp[udpn].pkt_hdr.caplen));
    text2_display(alludp[udpn].all,(int)(alludp[udpn].pkt_hdr.caplen));

    this->update();

}


void MainWindow::display(){

    //ui->tableWidget->setItem(1,0,new QTableWidgetItem("Jan"));
    //if(arpn)
    sem_wait(&mutex2);
    if(arpntmp!=arpn){
        arp_display();
    }
    else if(icmpntmp!=icmpn){
        icmp_display();
        if(allicmp[icmpn].pkt_hdr.ts.tv_sec==allicmp[icmpntmp].pkt_hdr.ts.tv_sec){ ipchart++; }
        else{  linechart->showipData(ipchart);ipchart=0;   }
    }
    else if(tcpntmp!=tcpn){
        tcp_display();
        if(alltcp[tcpn].pkt_hdr.ts.tv_sec==alltcp[tcpntmp].pkt_hdr.ts.tv_sec){ tcpchart++; ipchart++; }
        else{  linechart->showData(tcpchart); tcpchart=0;  linechart->showipData(ipchart);ipchart=0;  }
    }
    else if(udpntmp!=udpn){
        udp_display();
        if(alludp[udpn].pkt_hdr.ts.tv_sec==alludp[udpntmp].pkt_hdr.ts.tv_sec){ udpchart++;ipchart++;  }
        else{  linechart->showudpData(udpchart); udpchart=0;  linechart->showipData(ipchart);ipchart=0; }
    }
    else {
//         ui->tableWidget->insertRow(1);
    }
//    arpntmp++;icmpntmp++;tcpntmp++;udpntmp++;
    arpntmp=arpn; icmpntmp=icmpn; tcpntmp=tcpn; udpntmp=udpn;
    ui->tableWidget->scrollToBottom();

    ui->lineEdit->setText(QString::number(packet_number));
    ui->lineEdit_2->setText(QString::number(tcpn));
    ui->lineEdit_3->setText(QString::number(udpn));
    ui->lineEdit_4->setText(QString::number(tcpn+icmpn+udpn));
    ui->lineEdit_5->setText(QString::number(arpn));
    ui->lineEdit_6->setText(QString::number(icmpn));
    ui->lineEdit_7->setText(QString::number(capture_num));

    pthread_mutex_unlock(&mutex1);
    this->update();
}


void MainWindow::on_pushButton_clicked()
{
    start_times++;
    if(start_times>1){
        pthread_mutex_unlock(&mylock); open_close=true; button4times=0; return;
    }
    if(thr1.netstr==""){
         QMessageBox::information(this,"","请先设置网卡和过滤！！！");
         return;
    }
    process_or_not=true;
    open_close=true;
    thr.start();
    connect(&thr,SIGNAL(notify()),this,SLOT(display()));

    thr1.start();

//    pthread_t       receive_thread;
//    pthread_attr_t  receive_thread_attr;
//    pthread_attr_init(&receive_thread_attr);
//    pthread_attr_setdetachstate(&receive_thread_attr,PTHREAD_CREATE_DETACHED);
//    if(pthread_create(&receive_thread,&receive_thread_attr,begin_capture, (void *)this) < 0 ){

//        QMessageBox box;
//        QString str=QString("Can't capture now -- Error!");
//        box.setText(str);
//        box.exec();
//        return;

//    }

}

void MainWindow::on_pushButton_2_clicked()
{
    open_close=false;
}

void MainWindow::on_pushButton_3_clicked()
{
//    QMessageBox::information(this,""," red -> ip\n black -> tcp\n yellow -> udp");
    linechart->show();
}

void MainWindow::on_pushButton_4_clicked()
{
    selectDlg = new QDialog(this);
    selectDlg->setFixedSize(250,200);
    selectDlg->setWindowTitle (tr("设置过滤"));
    QLabel *label = new QLabel(tr("选择过滤:"),selectDlg);
            qcb = new QComboBox(selectDlg);
    QLabel *label1=new QLabel(tr("选择网卡:"),selectDlg);
            qcb1 = new QComboBox(selectDlg);
    QPushButton *OkButton = new QPushButton(tr("确定"),selectDlg);
    QPushButton *cancleButton = new QPushButton(tr("取消"),selectDlg);

    QHBoxLayout* layout3 = new QHBoxLayout();
    layout3->addWidget (label1);
    layout3->addWidget (qcb1);

    QHBoxLayout* layout = new QHBoxLayout();
    layout->addWidget (label);
    layout->addWidget (qcb);

    QHBoxLayout* layout1 = new QHBoxLayout();
    layout1->addWidget (OkButton);
    layout1->addWidget (cancleButton);

    QVBoxLayout* layout2 = new QVBoxLayout(selectDlg);
    layout2->addLayout (layout3);
    layout2->addLayout(layout);
    layout2->addLayout (layout1);


    qcb1->addItem("wlan0");
    qcb1->addItem("eth0");

    qcb->addItem("All");
    qcb->addItem ("ip and tcp");
    qcb->addItem ("ip and udp");
    qcb->addItem ("ip");
    qcb->addItem ("arp");
    qcb->addItem("icmp");

    connect(OkButton, SIGNAL(clicked()), this, SLOT(set()));
    connect(cancleButton, SIGNAL(clicked()), this, SLOT(dialogclose()));

    selectDlg->show();


}

void MainWindow::set(){
    settimes++;
    if(settimes==1){
        thr1.netstr=qcb1->currentText();
        thr1.filterstr=qcb->currentText();
        if(qcb->currentText()=="All"){ thr1.filterstr=" ";}
    }else{
        thr1.quit();thr1.terminate();
        thr1.netstr=qcb1->currentText();
        thr1.filterstr=qcb->currentText();
        if(qcb->currentText()=="All"){ thr1.filterstr=" ";}
        thr1.start();
        thr1.quit();thr1.terminate();
        thr1.netstr=qcb1->currentText();
        thr1.filterstr=qcb->currentText();
        if(qcb->currentText()=="All"){ thr1.filterstr=" ";}
    }
    selectDlg->close();
}

void MainWindow::dialogclose(){
    selectDlg->close();
}

void MainWindow::on_pushButton_5_clicked()
{
    button4times++;
    if(button4times==1){
        pthread_mutex_lock(&mylock);
    }else{
        QMessageBox::information(this,"","请先开始！！！");
        button4times--;
    }
//        open_close=false;
//        process_or_not=false;
}
